home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 12 / BBS in a box XII-2.iso / Files II / Prog / B-C / C++Source Code Fmtr.sit / Tests / UTabTEView.cp / UTabTEView.cp
Encoding:
Text File  |  1991-01-10  |  22.6 KB  |  816 lines  |  [TEXT/MPS ]

  1. //[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]
  2. /* Copyright © 1986-1990 Apple Computer, Inc.  All rights reserved. */
  3.  
  4.  
  5. #ifndef __UTabTEView__
  6. #include <UTabTEView.h>
  7. #endif
  8.  
  9. #ifndef __UDocument__
  10. #include <UDocument.h>
  11. #endif
  12.  
  13. #ifndef __UFailure__
  14. #include <UFailure.h>
  15. #endif
  16.  
  17. #ifndef __UMacAppUtilities__
  18. #include <UMacAppUtilities.h>
  19. #endif
  20.  
  21. #ifndef __Dialogs__
  22. #include <Dialogs.h>
  23. #endif
  24.  
  25. #ifndef __UPatch__
  26. #include <UPatch.h>
  27. #endif
  28.  
  29. #ifndef __UMemory__
  30. #include <UMemory.h>
  31. #endif
  32.  
  33. #ifndef __UMacAppGlobals__
  34. #include <UMacAppGlobals.h>
  35. #endif
  36.  
  37. #ifndef __UViewCoords__
  38. #include <UViewCoords.h>
  39. #endif
  40.  
  41. #ifndef __Menus__
  42. #include <Menus.h>
  43. #endif
  44.  
  45. #ifndef __UMenuMgr__
  46. #include <UMenuMgr.h>
  47. #endif
  48.  
  49. #ifndef __Errors__
  50. #include <Errors.h>
  51. #endif
  52.  
  53. #ifndef __ToolUtils__
  54. #include <ToolUtils.h>
  55. #endif
  56.  
  57. #ifndef __Packages__
  58. #include <Packages.h>
  59. #endif
  60.  
  61. #ifndef __Fonts__
  62. #include <Fonts.h>
  63. #endif
  64.  
  65. #ifndef __Script__
  66. #include <Script.h>
  67. #endif
  68.  
  69.  
  70.     //$J+*/                                                // These have storage allocated elsewhere 
  71.     extern short        HookedCQDProcsPtrOffset;                    // offset in object to the QDProcs record 
  72.     extern short        OldTEHooksRecOffset;                        // offset in object to the OldHooks record 
  73.  
  74.     extern TTabTEView*        curTabTEView;                     /* accessed synchronously by the QD
  75.                                                          replacement procs to get context */
  76.     //$J-
  77.  
  78.     short        pLastTheLength;
  79.     short        pLastTheWidthBefore;
  80.     TTabTEView* pLastSelf;
  81.     short        pLastTETxMeas;
  82.     short        pLastTheCharOffset;
  83.     short        pLastTheLine;
  84.  
  85. extern pascal void myTEDrawHook(void);
  86.  
  87. extern pascal void myTEWidthHook(void);
  88.  
  89. extern pascal void myTEHitTestHook(void);
  90.  
  91. extern pascal void myTEEOLHook(void);
  92.  
  93. pascal short CallOriginalTxMeas(short byteCount,
  94.                             Ptr        textAddr,
  95.                             Point& numer,
  96.                             Point& denom,
  97.                             FontInfo& info,
  98.                             ProcPtr actionProc) = { 0x205F, 0x4E90 };
  99. /*  MOVE.L  (A7)+,A0
  100. JSR (A0)
  101. */
  102.  
  103. pascal void CallOriginalText(short theLength,
  104.                            Ptr        theText,
  105.                            Point        numer,
  106.                            Point        denom,
  107.                            ProcPtr actionProc) = { 0x205F, 0x4E90 };
  108. /*  MOVE.L  (A7)+,A0
  109. JSR (A0)
  110. */
  111.  
  112. //--------------------------------------------------------------------------------------------------
  113. #pragma segment TEInit
  114.  
  115. pascal void InitUTabTEView(void)
  116. {
  117.     if (!gUTEViewInitialized)
  118.         InitUTEView();
  119.     
  120.     if (qTemplateViews)
  121.     {
  122.         // So linker doesn't strip TTabTEView class 
  123.         DontDeadStrip(TTabTEView);
  124.     }
  125. }
  126.  
  127. // Follows are the bottleneck procs for QuickDraw to perform tabs 
  128.  
  129. //--------------------------------------------------------------------------------------------------
  130. #pragma segment TERes
  131. //$Push*/
  132. #if qTrace 
  133. /*$D+*/
  134. #endif                     
  135. // we don't really need these guys traced! 
  136.  
  137. pascal short myTxMeas(short theLength,
  138.                   Ptr        theText,
  139.                   Point& numer,
  140.                   Point& denom,
  141.                   FontInfo& info)
  142. {
  143.     if (curTabTEView != NULL)
  144.         return curTabTEView->TETxMeas(theLength, theText, numer, denom, info);
  145.     else
  146. #if false
  147.         return CallOriginalTxMeas(theLength, theText, numer, denom, info,
  148.                                        curTabTEView->fOldCQDProcs.txMeasProc)
  149. #endif
  150.                     DebugStr("whoops!");
  151. }
  152. //$Pop
  153.  
  154. //--------------------------------------------------------------------------------------------------
  155. #pragma segment TERes
  156. //$Push*/
  157. #if qTrace 
  158. /*$D+*/
  159. #endif                     
  160.  // we don't really need these guys traced! 
  161.  
  162. pascal void myDrawText(short theLength,
  163.                      Ptr        theText,
  164.                      Point        numer,
  165.                      Point denom)
  166. {
  167.     if (curTabTEView != NULL)
  168.         curTabTEView->TEDrawText(theLength, theText, numer, denom);
  169.     else
  170. #if false
  171.         CallOriginalText(theLength, theText, numer, denom, curTabTEView->fOldCQDProcs.textProc);
  172. #endif
  173.           DebugStr("whoops!");
  174. }
  175. //$Pop
  176.  
  177. //--------------------------------------------------------------------------------------------------
  178. #pragma segment TERes
  179. //$Push*/
  180. #if qTrace
  181. /*$D+*/
  182. #endif                     
  183. // we don't really need these guys traced! 
  184.  
  185. pascal void TTabTEView::TEDrawText(short theLength,
  186.                                 Ptr        theText,
  187.                                 Point        numer,
  188.                                 Point denom)
  189. {
  190.     short        margin;
  191.     Point        currentPoint;
  192.     short        beginChar;
  193.  
  194.     TERec theTERec = **fHTE;
  195.     {
  196.         beginChar = 0;
  197.         margin = theTERec.destRect.left;
  198.         for (short i = 0; i <= theLength - 1; i++)
  199.         {
  200.             switch ( (unsigned char) *(theText + i)) 
  201.             {
  202.                 case chTab:
  203.                     CallOriginalText(i - beginChar, (Ptr) (theText + beginChar), numer, denom,
  204.                                      (ProcPtr) fOldCQDProcs.textProc);
  205.                     beginChar = i + 1;
  206.  
  207.                     GetPen(currentPoint);
  208.  
  209.                     if (fShowInvisibles)
  210.                         DrawChar(kVisibleTAB);
  211.  
  212.                     currentPoint.h = currentPoint.h - margin + fTabSize;
  213.                     currentPoint.h = (currentPoint.h / fTabSize) * fTabSize + margin + 1;
  214.  
  215.                     MoveTo(currentPoint.h, currentPoint.v);
  216.                     break;
  217.                 case chReturn:
  218.                     if (fShowInvisibles)
  219.                     {
  220.                         CallOriginalText(i - beginChar, (Ptr) (theText + beginChar), numer, denom,
  221.                                          (ProcPtr) fOldCQDProcs.textProc);
  222.                         beginChar = i + 1;
  223.  
  224.                         DrawChar(kVisibleCR);
  225.                     }
  226.                     break;
  227.                 case chSpace:
  228.                     if (fShowInvisibles)
  229.                     {
  230.                         CallOriginalText(i - beginChar, (Ptr)(theText + beginChar), numer, denom,
  231.                                          (ProcPtr) fOldCQDProcs.textProc);
  232.                         beginChar = i + 1;
  233.  
  234.                         DrawChar(kVisibleSpace);
  235.                     }
  236.                     break;
  237.             }
  238.         }
  239.     }
  240.  
  241.     CallOriginalText(theLength - beginChar, (Ptr) ( theText + beginChar), numer, denom,
  242.                      (ProcPtr) fOldCQDProcs.textProc);
  243. }
  244. //$Pop
  245.  
  246. //--------------------------------------------------------------------------------------------------
  247. #pragma segment TERes
  248. //$Push*/
  249. #if qTrace 
  250. /*$D+*/
  251. #endif         
  252. // we don't really need these guys traced! 
  253.  
  254. pascal short TTabTEView::TETextLength(Ptr theText,
  255.                                  short        theLength,
  256.                                  short        theWidthBefore,
  257.                                  Point& numer,
  258.                                  Point& denom,
  259.                                  FontInfo& info)
  260. {
  261.     short        beginChar;
  262.     short        theWidth;
  263.     QDByte        aByte;
  264.  
  265.     theWidth = 0;
  266.     beginChar = 0;
  267.     for (short i = 0 ; i <= theLength - 1; i++)
  268.     {
  269.         switch ( (unsigned char) *(theText + i)) 
  270.         {
  271.             case chTab:
  272.                 theWidth = theWidth + CallOriginalTxMeas(i - beginChar, (Ptr)(theText +
  273.                                                           beginChar), numer, denom, info,
  274.                                                           (ProcPtr) fOldCQDProcs.txMeasProc);
  275.                 beginChar = i + 1;
  276.                 theWidth = ((theWidth + fTabSize + theWidthBefore) / fTabSize) *
  277.                             fTabSize - theWidthBefore;
  278.                 break;
  279.             case chSpace:
  280.                 if (fShowInvisibles)
  281.                 {
  282.                     theWidth = theWidth + CallOriginalTxMeas(i - beginChar,(Ptr)(theText +
  283.                                                               beginChar), numer, denom, info,
  284.                                                               (ProcPtr) fOldCQDProcs.txMeasProc);
  285.                     beginChar = i + 1;
  286.                     aByte = QDByte(kVisibleSpace);
  287.                     theWidth = theWidth + CallOriginalTxMeas(1, &aByte, numer, denom, info,
  288.                                                               (ProcPtr) fOldCQDProcs.txMeasProc);
  289.                 }
  290.                 break;
  291.             case chReturn:
  292.                 if (fShowInvisibles)
  293.                 {
  294.                     theWidth = theWidth + CallOriginalTxMeas(i - beginChar, (Ptr)(theText +
  295.                                                               beginChar), numer, denom, info,
  296.                                                               (ProcPtr) fOldCQDProcs.txMeasProc);
  297.                     beginChar = i + 1;
  298.                     aByte = QDByte(kVisibleCR);
  299.                     theWidth = theWidth + CallOriginalTxMeas(1, &aByte, numer, denom, info,
  300.                                                               (ProcPtr) fOldCQDProcs.txMeasProc);
  301.                 }
  302.                 break;
  303.         }
  304.     }
  305.  
  306.     return (theWidth + CallOriginalTxMeas(theLength - beginChar, (Ptr)(theText +
  307.                                                   beginChar), numer, denom, info,
  308.                                                   (ProcPtr) fOldCQDProcs.txMeasProc) );
  309. }
  310. //$Pop
  311.  
  312. //--------------------------------------------------------------------------------------------------
  313. #pragma segment TERes
  314. //$Push*/
  315. #if qTrace 
  316. /*$D+*/
  317. #endif                     
  318. // we don't really need these guys traced! 
  319.  
  320. pascal short TTabTEView::TETxMeas(short theLength,
  321.                              Ptr        theText,
  322.                              Point& numer,
  323.                              Point& denom,
  324.                              FontInfo& info)
  325. {
  326.     short        TheCharOffset;
  327.     short        theline;
  328.     short        theWidthBefore;
  329.  
  330.     
  331.     /*
  332.     Find which line in the TE the text pointed to by theText starts on and measure the
  333.     distance between the start of the line and the position in theline pointed to by theText.
  334.     This whole scheme depends on textedit passing us a pointer to the actual hText->
  335.     */
  336.  
  337.     TERec& theTERec = **fHTE;
  338.     {
  339.         // find out what line we're currently on 
  340.         //!!! Note cast
  341.         TheCharOffset = (short) (StripLong(theText) - StripLong(*theTERec.hText)); /* hText could have been
  342.                                                                             a resource */
  343.  
  344.         if ((this == pLastSelf) && (TheCharOffset == pLastTheCharOffset))
  345.         {
  346.             theline = pLastTheLine;
  347.         }        
  348.         else                                            /* Scan backward thru the line starts array
  349.                                                          for a linestart less than TheCharOffset */
  350.         {
  351.             for ( theline = (short) Max(theTERec.nLines - 1, 0); theline >= 0 ; theline-- ) //!!! Note long->short cast
  352.                 if (theTERec.lineStarts[theline] <= TheCharOffset)
  353.                     break;
  354.         }
  355.  
  356.         // if the line is the same we may be able to save some calculation by caching 
  357.  
  358. #if FALSE
  359.         //### !NOW 
  360.         if ((this == pLastSelf) && (theline == pLastTheLine))
  361.         {
  362.             if (TheCharOffset < pLastTheCharOffset)) /* starts sooner on line. saved
  363.                                                           theWidthBefore info is useless */
  364.             {
  365.                 if ((lineStarts[theline] == TheCharOffset) || (lineStarts[theline] < 0)) /* the
  366.                        beginning of a line or end of text */
  367.                     theWidthBefore = 0;
  368.                 else
  369.                     theWidthBefore = TETextLength((Ptr)((*hText) + lineStarts[theline]),
  370.                                                    TheCharOffset - lineStarts[theline], 0, numer,
  371.                                                    denom, info);
  372.                 pLastTETxMeas = TETextLength(theText, theLength, theWidthBefore, numer, denom,
  373.                                               info);
  374.             }            
  375.             else if (TheCharOffset > pLastTheCharOffset)) /* starts later on line. Attempt to
  376.                                                                re-use some width before info */
  377.             {
  378.                 if (TheCharOffset < (pLastTheCharOffset + pLastTheLength))) /* starts sooner than
  379.                        end of last run pLastTETxMeas is useless */
  380.                 {
  381.                     theWidthBefore = TETextLength(Ptr((*hText) + pLastTheCharOffset),
  382.                                                    TheCharOffset - pLastTheCharOffset,
  383.                                                    theWidthBefore, numer, denom, info);
  384.                     pLastTETxMeas = TETextLength(theText, theLength, theWidthBefore, numer, denom,
  385.                                                   info);
  386.                 }                
  387.                 else if (TheCharOffset > (pLastTheCharOffset + pLastTheLength)))
  388.                 {
  389.                     theWidthBefore = pLastTheWidthBefore + pLastTETxMeas;
  390.                     theWidthBefore = TETextLength(Ptr((*hText) + pLastTheCharOffset +
  391.                                                        pLastTheLength), TheCharOffset -
  392.                                                    (pLastTheCharOffset + pLastTheLength),
  393.                                                    theWidthBefore, numer, denom, info);
  394.                     pLastTETxMeas = TETextLength(theText, theLength, theWidthBefore, numer, denom,
  395.                                                   info);
  396.                 }                
  397.                 else                                    // must be equal 
  398.                 {
  399.                     theWidthBefore = pLastTheWidthBefore + pLastTETxMeas;
  400.                     pLastTETxMeas = TETextLength(theText, theLength, theWidthBefore, numer, denom,
  401.                                                   info)
  402.                 }                
  403.             }            
  404.             else                                        // must be equal starting position 
  405.             {
  406.                 if (theLength < pLastTheLength))
  407.                     {
  408.                     if ((lineStarts[theline] == TheCharOffset) || (lineStarts[theline] < 0)) /* the
  409.                            beginning of a line or end of text */
  410.                         theWidthBefore = 0
  411.                     else
  412.                         theWidthBefore = TETextLength((Ptr)((*hText) + lineStarts[theline]),
  413.                                                        TheCharOffset - lineStarts[theline], 0,
  414.                                                        numer, denom, info);
  415.                     pLastTETxMeas = TETextLength(theText, theLength, theWidthBefore, numer, denom,
  416.                                                   info);
  417.                     }                else if (theLength > pLastTheLength))
  418.                     {
  419.                     pLastTETxMeas = pLastTETxMeas + TETextLength((Ptr)(theText +
  420.                                                                   pLastTheLength), theLength -
  421.                                                                   pLastTheLength,
  422.                                                                   pLastTheWidthBefore +
  423.                                                                   pLastTETxMeas, numer, denom, info)
  424.                     }                
  425.                     else                                    // must be equal 
  426.                     {
  427.                     pLastTETxMeas = pLastTETxMeas;
  428.                     }
  429.  
  430.             }
  431.         }        
  432.         else                                            // line not the same. no caching available 
  433. #endif
  434.         {
  435.             if ((theTERec.lineStarts[theline] == TheCharOffset) || (theTERec.lineStarts[theline] < 0)) /* the
  436.                    beginning of a line or end of text */
  437.                 theWidthBefore = 0;
  438.             else
  439.                 theWidthBefore = TETextLength((Ptr)((*theTERec.hText) + theTERec.lineStarts[theline]),
  440.                                                TheCharOffset - theTERec.lineStarts[theline], 0, numer,
  441.                                                denom, info);
  442.             pLastTETxMeas = TETextLength(theText, theLength, theWidthBefore, numer, denom, info);
  443.         }
  444.     }
  445.  
  446.     pLastTheWidthBefore = theWidthBefore;
  447.     pLastTheCharOffset = TheCharOffset;
  448.     pLastTheLine = theline;
  449.     pLastTheLength = theLength;
  450.     pLastSelf = this;
  451.     return pLastTETxMeas;
  452. }
  453. //$Pop
  454.  
  455. //--------------------------------------------------------------------------------------------------
  456. #pragma segment TERes
  457.  
  458. pascal void TTabTEView::WithHookedGrafProcsDo (pascal void (*whatToDo) (void* staticLink), void* staticLink)
  459. {
  460.     QDProcsPtr        oldGrafProcs;                 /* the grafprocs pointer found in the TE's
  461.                                                      grafport */
  462.     TTabTEView*        oldCurTEView;                 // the saved setting of the curTEView 
  463.  
  464. /* Make this available to the hooked grafprocs that will be invoked later
  465.  save the old curTabTEView first */
  466.     oldCurTEView = curTabTEView;
  467.     curTabTEView = this;
  468.  
  469.     // save its old grafprocs pointer 
  470.     oldGrafProcs = (**fHTE).inPort->grafProcs;
  471.     (**fHTE).inPort->grafProcs = QDProcsPtr(fHookedCQDProcsPtr);
  472.  
  473.     // Do what we were called for 
  474.     whatToDo(staticLink);
  475.  
  476.     // restore the old curTabTEView, grafprocs and that showed we were hooked in 
  477.  
  478.     curTabTEView = oldCurTEView;
  479.     (**fHTE).inPort->grafProcs = oldGrafProcs;
  480. }
  481.  
  482. //--------------------------------------------------------------------------------------------------
  483. #pragma segment TERes
  484.  
  485. typedef pascal void (*WhatToDoType) (void* staticLink);
  486. class CWhatToDo
  487. {
  488.     TTabTEView*     fThis;
  489.     VPoint&            fTheMouse;
  490.     TDeviceEvent*&     fEvent;
  491.     Point&            fHysteresis;
  492. public:
  493.     // Constructor
  494.     CWhatToDo(TTabTEView* theThis,
  495.                 VPoint& theMouse,
  496.                 TDeviceEvent*        event,
  497.                 Point& hysteresis ):
  498.         fThis(theThis), fTheMouse(theMouse), fEvent(event), fHysteresis(hysteresis) {};
  499.         
  500.     pascal void WhatToDo(void);
  501. };
  502.  
  503. #pragma segment TERes
  504. pascal void CWhatToDo::WhatToDo(void)
  505. {
  506.     fThis->TTEView::DoMouseCommand(fTheMouse, fEvent, fHysteresis); // INHERITED
  507. };
  508.  
  509. #pragma segment TERes
  510. pascal void TTabTEView::DoMouseCommand(VPoint& theMouse,
  511.                                    TDeviceEvent*        event,
  512.                                    Point& hysteresis) // override 
  513.  
  514.  
  515. {
  516.     CWhatToDo aCWhatToDo(this,theMouse,event,hysteresis);
  517.     // lousy TE (6.0) doesn't always respect TECustomHook! 
  518.     WithHookedGrafProcsDo( (WhatToDoType) &CWhatToDo::WhatToDo,&aCWhatToDo);
  519. }
  520.  
  521. //--------------------------------------------------------------------------------------------------
  522. #pragma segment TERes
  523.  
  524. pascal void TTabTEView::DoSetupMenus(void) // override 
  525. {
  526.     inherited::DoSetupMenus();
  527.     
  528.     Enable(cIncTabs, TRUE);
  529.     Enable(cDecTabs, TRUE);
  530.     EnableCheck(cShowInvs, TRUE, fShowInvisibles);            /**/
  531. }
  532.  
  533. //--------------------------------------------------------------------------------------------------
  534. #pragma segment TESelCommand
  535.  
  536. pascal void TTabTEView::DoMenuCommand(CmdNumber aCmdNumber) // override 
  537. {
  538.     switch (aCmdNumber) 
  539.     {
  540.         case cIncTabs:
  541.             TSetTabCommand* aSetTabCmd1 = new TSetTabCommand;
  542.             
  543.             aSetTabCmd1->ISetTabCommand(this, aCmdNumber, fTabSize + 1);
  544.             this->PostCommand(aSetTabCmd1);
  545.             break;
  546.         case cDecTabs:
  547.             TSetTabCommand* aSetTabCmd2 = new TSetTabCommand;
  548.             
  549.             aSetTabCmd2->ISetTabCommand(this, aCmdNumber, fTabSize - 1);
  550.             this->PostCommand(aSetTabCmd2);
  551.             break;
  552.         case cShowInvs:
  553.             TShowInvsCommand* aShowInvsCmd = new TShowInvsCommand;
  554.             
  555.             aShowInvsCmd->IShowInvsCommand(this, aCmdNumber, fShowInvisibles);
  556.             this->PostCommand(aShowInvsCmd);
  557.             break;
  558.         default:
  559.             inherited::DoMenuCommand(aCmdNumber);
  560.     }
  561. }
  562.  
  563. //--------------------------------------------------------------------------------------------------
  564. #pragma segment TEOpen
  565.  
  566. pascal void TTabTEView::IRes(TDocument* itsDocument,
  567.                           TView*        itsSuperView,
  568.                           Ptr& itsParams) // override 
  569. {
  570.         ProcPtr        aProcPtr;
  571.  
  572.     
  573.     fHookedCQDProcsPtr = NULL;
  574.  
  575.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  576.  
  577.     fHookedCQDProcsPtr = CQDProcsPtr(NewPermPtr(sizeof(CQDProcs)));
  578.     fTabSize = kDefaultTabSize;
  579.     fShowInvisibles = FALSE;
  580.     fControlChars = __SetBit__(fControlChars) | __SetBit__(chTab); // fControlChars = fControlChars + [chTab];    // tell TTE to accept tabs 
  581.  
  582.     if (fStyleType)                                    // only for style right now… sorry! 
  583.     {
  584.         if (fHTE != NULL)
  585.         {
  586.             // Storing this in the refcon should be in MacApp 
  587.             (*GetStylHandle(fHTE))->teRefCon = (long)(this);
  588.  
  589.             // let the ASM code know the offset of some of our structures 
  590.             HookedCQDProcsPtrOffset = (short) (StripLong(&fHookedCQDProcsPtr) - StripLong((*(Handle)(this)))); //!!! Note long->short cast
  591.             OldTEHooksRecOffset = (short) (StripLong(&fOldTEHooksRec) - StripLong((*(Handle)(this)))); //!!! Note long->short cast
  592.  
  593.             //  set up custom hooks into my TE to handle tabs 
  594.             aProcPtr = (ProcPtr) &myTEDrawHook;
  595.             TECustomHook(intDrawHook, aProcPtr, fHTE);
  596.             fOldTEHooksRec.DrawHook = aProcPtr;
  597.  
  598.             aProcPtr = (ProcPtr) &myTEWidthHook;
  599.             TECustomHook(intWidthHook, aProcPtr, fHTE);
  600.             fOldTEHooksRec.WidthHook = aProcPtr;
  601.  
  602.             aProcPtr = (ProcPtr) &myTEHitTestHook;
  603.             TECustomHook(intHitTestHook, aProcPtr, fHTE);
  604.             fOldTEHooksRec.HitTestHook = aProcPtr;
  605.  
  606.         }
  607.     }
  608.     this->BeInPort(GetGrafPort());
  609. }
  610.  
  611. //--------------------------------------------------------------------------------------------------
  612. #pragma segment TENonRes
  613.  
  614. pascal void TTabTEView::BeInPort(GrafPtr itsPort) // override 
  615. // save a copy of the currently effective GrafProcs and create a new version of the hooked procs 
  616. {
  617.     CQDProcs        theCProcs;
  618.     QDProcs        theProcs;
  619.     QDProcsPtr        aQDProcsPtr;
  620.     CGrafPtr        itsCPort;
  621.     
  622.     inherited::BeInPort(itsPort);
  623.  
  624.     if ((fHTE != NULL) && (fHookedCQDProcsPtr != NULL))
  625.     {
  626.         if (IsColorPort(itsPort))
  627.         {
  628.             itsCPort = (CGrafPtr) itsPort;
  629.             if (itsCPort->grafProcs == NULL)
  630.             {
  631.                 SetStdCProcs(theCProcs);
  632.                 fOldCQDProcs = theCProcs;
  633.             }            
  634.             else
  635.                 fOldCQDProcs = *(CQDProcsPtr)(itsCPort->grafProcs);
  636.         }        
  637.         else
  638.         {
  639.             if (itsPort->grafProcs == NULL)
  640.             {
  641.                 SetStdProcs(theProcs);
  642.                 aQDProcsPtr = (QDProcsPtr)(&fOldCQDProcs);
  643.                 (*aQDProcsPtr) = theProcs;
  644.             }            
  645.             else
  646.             {
  647.                 aQDProcsPtr = (QDProcsPtr)(&fOldCQDProcs);
  648.                 (*aQDProcsPtr) = *(itsPort->grafProcs);
  649.             }
  650.         }
  651.  
  652.         // stuff my replacements into the hooked grafprocs 
  653.         (*fHookedCQDProcsPtr) = fOldCQDProcs;
  654.         fHookedCQDProcsPtr->textProc = (Ptr) &myDrawText;
  655.         fHookedCQDProcsPtr->txMeasProc = (Ptr) &myTxMeas;
  656.     }    
  657. }
  658.  
  659. //--------------------------------------------------------------------------------------------------
  660. #pragma segment TEOpen
  661.  
  662. pascal void TTabTEView::SetTabSize(short newSize, Boolean redraw)
  663. {
  664.     fTabSize = newSize;
  665.     fSpecsChanged = TRUE;
  666.     SynchView(FALSE);
  667.     if (redraw)
  668.         this->ForceRedraw();
  669. }
  670.  
  671. //--------------------------------------------------------------------------------------------------
  672. #pragma segment TERes
  673.  
  674. pascal void TTabTEView::ShowInvisibles(Boolean showEm, Boolean redraw)
  675. {
  676.     fShowInvisibles = showEm;
  677.     if (redraw)
  678.         this->ForceRedraw();
  679. }
  680.  
  681. //--------------------------------------------------------------------------------------------------
  682. #pragma segment TEFields
  683.  
  684. pascal void TTabTEView::Fields(TObject* obj) // override 
  685. {
  686.     obj->DoToField("TTabTEView", (Ptr)NULL, bClass);
  687.     obj->DoToField("fTabSize", (Ptr)&fTabSize, bInteger);
  688.     obj->DoToField("fShowInvisibles", (Ptr)&fShowInvisibles, bBoolean);
  689.     if (IsColorPort(GetGrafPort()))
  690.     {
  691.         obj->DoToField("fOldCQDProcs", (Ptr)&fOldCQDProcs, bCQDProcs);
  692.         obj->DoToField("(*fHookedCQDProcsPtr)", (Ptr) &(*fHookedCQDProcsPtr), bCQDProcs);
  693.     }    
  694.     else
  695.     {
  696.         obj->DoToField("fOldCQDProcs", (Ptr)&fOldCQDProcs, bQDProcs);
  697.         obj->DoToField("(*fHookedCQDProcsPtr)", (Ptr) &(*fHookedCQDProcsPtr), bQDProcs);
  698.     }
  699.     inherited::Fields(obj);
  700. }
  701.  
  702. //--------------------------------------------------------------------------------------------------
  703. #pragma segment TESelCommand
  704.  
  705. pascal void TSetTabCommand::ISetTabCommand(TView* itsView,
  706.                                 CmdNumber        itsCmdNumber,
  707.                                 short tabSetting)
  708. {
  709.     this->ICommand(itsCmdNumber, itsView->fDocument, itsView);
  710.     if (fView->IsMemberClass(GetClassIDFromName("TTabTEView")))
  711.         fOldTabSetting = ((TTabTEView*) itsView)->fTabSize;
  712.     else
  713.         fOldTabSetting = 0;
  714.     fNewTabSetting = tabSetting;
  715. }
  716.  
  717. //--------------------------------------------------------------------------------------------------
  718. #pragma segment TEDoCommand
  719.  
  720. pascal void TSetTabCommand::DoIt(void) // override 
  721. // sets new tabs, then calls ForceRedraw 
  722. {
  723.     if (fView->Focus());                                //??? What if Focus fails
  724.     if (fView->IsMemberClass(GetClassIDFromName("TTabTEView")))
  725.         ((TTabTEView*) fView)->SetTabSize(fNewTabSetting, kRedraw);
  726. }
  727.  
  728. //--------------------------------------------------------------------------------------------------
  729. #pragma segment TEDoCommand
  730.  
  731. pascal void TSetTabCommand::RedoIt(void) // override 
  732. // calls DoIt 
  733. {
  734.     this->DoIt();
  735. }
  736.  
  737. //--------------------------------------------------------------------------------------------------
  738. #pragma segment TEDoCommand
  739.  
  740. pascal void TSetTabCommand::UndoIt(void) // override 
  741. // restores previous tab setting 
  742. {
  743.     if (fView->Focus());                                //??? What if Focus fails
  744.     if (fView->IsMemberClass(GetClassIDFromName("TTabTEView")))
  745.         ((TTabTEView*) fView)->SetTabSize(fOldTabSetting, kRedraw);
  746. }
  747.  
  748. //--------------------------------------------------------------------------------------------------
  749. #pragma segment TEFields
  750.  
  751. // Debugging 
  752.  
  753. pascal void TSetTabCommand::Fields(TObject* obj) // override 
  754. {
  755.     obj->DoToField("TSetTabCommand", (Ptr)NULL, bClass);
  756.     obj->DoToField("fOldTabSetting", (Ptr)&fOldTabSetting, bInteger);
  757.     obj->DoToField("fNewTabSetting", (Ptr)&fNewTabSetting, bInteger);
  758.  
  759.     inherited::Fields(obj);
  760. }
  761.  
  762. //--------------------------------------------------------------------------------------------------
  763. #pragma segment TESelCommand
  764.  
  765. pascal void TShowInvsCommand::IShowInvsCommand(TView* itsView,
  766.                                 CmdNumber itsCmdNumber,
  767.                                 Boolean invsWereShown)
  768.     {
  769.     ICommand(itsCmdNumber, itsView->fDocument, itsView);
  770.     fInvsWereShown = invsWereShown;
  771.     }
  772.  
  773. //--------------------------------------------------------------------------------------------------
  774. #pragma segment TEDoCommand
  775.  
  776. pascal void TShowInvsCommand::DoIt(void) // override 
  777. // sets new tabs, then calls ForceRedraw 
  778.     {
  779.     if (fView->Focus());                                //??? What if Focus fails
  780.     if (fView->IsMemberClass(GetClassIDFromName("TTabTEView")))
  781.         ((TTabTEView*) fView)->ShowInvisibles(!fInvsWereShown, kRedraw);
  782.     }
  783.  
  784. //--------------------------------------------------------------------------------------------------
  785. #pragma segment TEDoCommand
  786.  
  787. pascal void TShowInvsCommand::RedoIt(void) // override 
  788. // calls DoIt 
  789. {
  790.     this->DoIt();
  791. }
  792.  
  793. //--------------------------------------------------------------------------------------------------
  794. #pragma segment TEDoCommand
  795.  
  796. pascal void TShowInvsCommand::UndoIt(void) // override 
  797. // restores previous tab setting 
  798. {
  799.     if (fView->Focus());                                //??? What if Focus fails
  800.     if (fView->IsMemberClass(GetClassIDFromName("TTabTEView")))
  801.         ((TTabTEView*) fView)->ShowInvisibles(fInvsWereShown, kRedraw);
  802. }
  803.  
  804. //--------------------------------------------------------------------------------------------------
  805. #pragma segment TEFields
  806.  
  807. // Debugging 
  808.  
  809. pascal void TShowInvsCommand::Fields(TObject* obj) // override 
  810. {
  811.     obj->DoToField("TShowInvsCommand", (Ptr)NULL, bClass);
  812.     obj->DoToField("fInvsWereShown", (Ptr)&fInvsWereShown, bBoolean);
  813.  
  814.     inherited::Fields(obj);
  815. }
  816.